#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "run.c"
typedef struct string {
	char linestr[1024];
	struct string *next;
}String;

int llVM_compile(char *new_build,char *clang_path,char *source_programPath,char *IgnorePassPath,char *outRunfileNamePath){
	char command2[1024];  
	strcpy(command2,clang_path);
	strcat(command2, "clang ");
	strcat(command2, source_programPath);
	strcat(command2, " -O0 -march=");
   	strcat(command2, new_build);
	strcat(command2, " -mllvm -file-path-that-stores-ignore-pass-names=");
	strcat(command2, IgnorePassPath); 
	strcat(command2, " -mllvm -ignore-middle-end -o a.out"); 
	printf("%s\n",command2);
	int result1 = system(command2); 
	printf("result1=%d\n",result1);
	if(result1==0){
		int result1 = run_out("./a.out",outRunfileNamePath,10); 
		return result1;
	}else{
		return -5;
	}
}
int llvm_compile_UnixBench(char *source_programPath,char *outRunfileNamePath){
	char command2[1024]="make -C ";
	strcat(command2,source_programPath);
	char command1[1024]="make clean -C ";
	strcat(command1,source_programPath);
	system(command1);
	int result1 = system(command2);
	if(result1==0){
		int re=run_out("./Run","outRunfileNamePath",10);
		if(re==1)re=0;
		return re;
	}else{
		return -5;
	}
}
void print_String(String *head){
	String *p=head;
	printf("------------------------------shuchu---------------\n");
	p=p->next;
	while(p!=NULL){
		printf("%s ",p->linestr);
		p=p->next;
	}
}
String *read_TXTfileHead(char *filepath){
	FILE *file;  
    char line[1024]; // 假设每行不超过1023个字符（加上换行符）  
	String *head,*p;
	head=(String *)malloc(sizeof(String));
	head->next=NULL;
    // 打开文件  
    file = fopen(filepath, "r");  
    if (file == NULL) {  
        perror("Error opening file");  
        return head;  
    }  
  	int i=0;
    // 读取文件，直到文件末尾或发生错误  
    while (fgets(line, sizeof(line), file) != NULL) {  
        // 在这里处理每一行，例如打印它  
		p=(String *)malloc(sizeof(String));
		p->next=NULL;
		strcpy(p->linestr,line);
		p->next=head->next;
		head->next=p;
        printf("第%d条pass:%s", ++i,line);  
    }  
    // 关闭文件  
    fclose(file);  
	return head;
}
void save_StringTOfile(String *head,char *filePath){
	String *p=head->next;
	FILE *fp=fopen(filePath,"w");
	while(p){
		// fprintf(fp,"%s",p->linestr);
		fputs(p->linestr,fp);
		p=p->next;
	}
	fclose(fp);
}

void AllBackendName_one_IgnorePass(char *new_buildPath,char *clangBinPath,char *source_programPath,char *AllBackendNamePath,char *IgnorePassPath,char *compulsory_passPath){
	
}
void AllBackendName_add_IgnorePass(char *new_buildPath,char *clangBinPath,char *source_programPath,char *AllBackendNamePath,char *IgnorePassPath,char *compulsory_passPath){
	String *passHead,*pass;
	String *IgnorePassHead,*IgnorePass;
	String *compulsory_passHead,*compulsory_pass;
	passHead=read_TXTfileHead(AllBackendNamePath);//读取所有的pass，并逆置
	pass=passHead->next;

	//IgnorePassHead保存需要关闭的pass
	IgnorePassHead=(String *)malloc(sizeof(String));
	IgnorePassHead->next=NULL;
	IgnorePass=IgnorePassHead;

	//保存compulsory_pass，这个使用头插法 逆置
	compulsory_passHead=(String *)malloc(sizeof(String));
	compulsory_passHead->next=NULL;
	while(pass){
		IgnorePass->next=(String *)malloc(sizeof(String));
		IgnorePass->next->next=NULL;
		strcpy(IgnorePass->next->linestr,pass->linestr);
		save_StringTOfile(IgnorePassHead,IgnorePassPath);//先将新的pass记录到结构体中并保存到文件，此时指针并不后移，方便后续的删除
		int llvmcc=llVM_compile(new_buildPath,clangBinPath,source_programPath,IgnorePassPath,stringLink_(stringLink_("/home/gou/文档/STREAM/out/",pass->linestr),".txt"));
		// int llvmcc=llvm_compile_UnixBench(source_programPath,stringLink_(stringLink_("/home/gou/文档/llvm/byte-unixbench-master/UnixBench/out/",pass->linestr),".txt"));//编译UnixBench项目
		// print_String(IgnorePassHead);
		if(llvmcc==0){
			//运行编译都通过
			IgnorePass=IgnorePass->next;//这个不是compulsory_pass，保存这个pass到IgnorePassHead
		}else{
			//出现错误 这是一个compulsory_pass
			compulsory_pass=(String *)malloc(sizeof(String));
			compulsory_pass->next=NULL;//从创建新的compulsory_pass节点
			char compass[1024]="";
// 			1 表示运行超时
// 3 表示运行失败
// 4 表示运行异常
// 5 表示其他错误
			if(llvmcc==-5){
				strcpy(compass,"编译失败  ");
				strcat(compass,pass->linestr);
			}else if(llvmcc==1){
				strcpy(compass,"运行超时  ");
				strcat(compass,pass->linestr);
			}else if(llvmcc==3){
				strcpy(compass,"运行失败  ");
				strcat(compass,pass->linestr);
			}else if(llvmcc==4){
				strcpy(compass,"运行异常  ");
				strcat(compass,pass->linestr);
			}else if(llvmcc==5){
				strcpy(compass,"其他错误  ");
				strcat(compass,pass->linestr);
			}
			strcpy(compulsory_pass->linestr,compass);//这是一个compulsory_pass，保存这个pass到compulsory_pass
			compulsory_pass->next=compulsory_passHead->next;
			compulsory_passHead->next=compulsory_pass;//头插法 逆置
			IgnorePass->next=NULL;//这个是compulsory_pass，不保存这个pass到IgnorePassHead中
			// save_StringTOfile(IgnorePassHead,IgnorePassPath);
			save_StringTOfile(compulsory_passHead,compulsory_passPath);//将整个compulsory_passHead结构体保存到文件中
		}
		pass=pass->next;
	}
}
int main(){
	char new_build[20]="znver2";
	// char new_build[20]="haswell";
	char clangBin[1024]="/home/gou/APP/llvm17.1/bin/";
	// char AllBackendName[1024]="/home/gou/文档/llvm/AllBackendName";
	char AllBackendName[1024]="/home/gou/文档/llvm/AllBackendName_haswell_x86";
	char IgnorePass[1024]="/home/gou/文档/llvm/IgnorePass";
	// char source_program[1024]="/home/gou/文档/STREAM/stream.c";
	char source_program[1024]="/home/gou/文档/llvm/byte-unixbench-master/UnixBench";
	char compulsory_pass[1024]="/home/gou/文档/llvm/compulsory_pass.txt";

	// // AllBackendName_one_IgnorePass(new_build,clangBin,source_program,AllBackendName,IgnorePass,compulsory_pass);
	AllBackendName_add_IgnorePass(new_build,clangBin,source_program,AllBackendName,IgnorePass,compulsory_pass);
	// // int result1 = system("make -C /home/gou/文档/llvm/byte-unixbench-master/UnixBench run");
	// int result1 = run_out("Run");
	// printf("%d\n",result1);

	return 0;
}
